using DesktopApp.Models; // For RuleType
using DesktopApp.ViewModels; // For RuleItemViewModel
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace DesktopApp.ViewModels.Services
{
    public class LogProcessingService : ILogProcessingService
    {
        // Precompile common regex patterns once for the service lifetime
        private readonly Regex _timestampRegex = new Regex(@"\b\d{1,2}:\d{2}(:\d{2})?(\.\d{1,3})?\b", RegexOptions.Compiled);
        private readonly Regex _filePathRegex = new Regex(@"(b(at|in)\s+)?([a-zA-Z]:)?([/\.\w-\]\\[]+)+(\.\w+)(:\d+)?(:\d+)?", RegexOptions.Compiled);

        public Task<string> ProcessLogAsync(string originalLog, IEnumerable<RuleItemViewModel> activeRules)
        {
            // Run the processing logic asynchronously (although currently it's mostly CPU-bound)
            return Task.Run(() =>
            {
                Debug.WriteLine("LogProcessingService: Starting log processing...");
                if (string.IsNullOrEmpty(originalLog)) return string.Empty;

                var rulesList = activeRules.ToList(); // Convert to list for easier access
                if (!rulesList.Any())
                {
                    Debug.WriteLine("LogProcessingService: No active rules provided.");
                    return originalLog; // No rules enabled, return original
                }

                var lines = originalLog.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
                var resultBuilder = new StringBuilder(originalLog.Length); // Pre-allocate builder capacity

                // Precompile rule-specific Regex patterns for this run
                var regexCache = new Dictionary<string, Regex>();
                foreach(var rule in rulesList.Where(r => r.Type == RuleType.RegexReplace && !string.IsNullOrEmpty(r.Pattern))){
                    if (!regexCache.ContainsKey(rule.Pattern!)){
                        try { regexCache[rule.Pattern!] = new Regex(rule.Pattern!, RegexOptions.Compiled); }
                        catch (ArgumentException ex) { Debug.WriteLine($"LogProcessingService: Invalid regex pattern '{rule.Pattern}' in rule '{rule.Name}': {ex.Message}"); /* Handle error? Maybe log it */ }
                    }
                }

                foreach (string line in lines)
                {
                    string currentLine = line;
                    bool lineExcluded = false;

                    foreach (var rule in rulesList)
                    {
                        if (lineExcluded) break; // Skip further processing if line already excluded

                        try
                        {
                            switch (rule.Type)
                            {
                                case RuleType.FilterExcludes:
                                    if (!string.IsNullOrEmpty(rule.Keyword) && currentLine.Contains(rule.Keyword, StringComparison.OrdinalIgnoreCase))
                                    {
                                        lineExcluded = true;
                                    }
                                    break;

                                case RuleType.FilterIncludes:
                                     // If *any* include rule is active, a line is only kept if it matches *at least one* include rule.
                                     // We need to check all include rules first.
                                     // This simple check excludes if *this specific* include rule doesn't match, which isn't quite right
                                     // if multiple include rules exist. A better approach requires pre-filtering or different logic.
                                     // For simplicity, let's assume only one effective 'include' rule or combine keywords.
                                    if (!string.IsNullOrEmpty(rule.Keyword) && !currentLine.Contains(rule.Keyword, StringComparison.OrdinalIgnoreCase))
                                    {
                                         lineExcluded = true; 
                                    }
                                    break;

                                case RuleType.KeywordReplace:
                                    if (!string.IsNullOrEmpty(rule.Keyword))
                                    {
                                        currentLine = currentLine.Replace(rule.Keyword, rule.Replacement ?? string.Empty, StringComparison.OrdinalIgnoreCase);
                                    }
                                    break;

                                case RuleType.RegexReplace:
                                    if (!string.IsNullOrEmpty(rule.Pattern) && regexCache.TryGetValue(rule.Pattern!, out var regex))
                                    {
                                        currentLine = regex.Replace(currentLine, rule.Replacement ?? string.Empty);
                                    }
                                    break;

                                case RuleType.RemoveTimestamps:
                                    currentLine = _timestampRegex.Replace(currentLine, string.Empty);
                                    break;

                                case RuleType.RemoveFilePaths:
                                    currentLine = _filePathRegex.Replace(currentLine, string.Empty);
                                    break;

                                // Add cases for other potential future rule types
                            }
                        }
                        catch (Exception ex)
                        {
                            Debug.WriteLine($"LogProcessingService: Error applying rule '{rule.Name}' to line: {ex.Message}");
                            // Optionally skip this rule for this line or handle differently
                        }
                    }

                    if (!lineExcluded)
                    {
                        resultBuilder.AppendLine(currentLine);
                    }
                }
                
                var result = resultBuilder.ToString().TrimEnd('\r', '\n');
                Debug.WriteLine("LogProcessingService: Log processing finished.");
                return result;
            });
        }
    }
} 